package com.his.aop;

import com.his.annotation.RequireRoles;
import com.his.common.Const;
import com.his.common.Rsp;
import com.his.entity.HisUser;
import com.his.entity.Patient;
import com.his.utils.JWTUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 登录用户的权限验证
 *
 * @author dawn
 */
@Aspect
@Component
@Order(2)
public class RoleCheck {

    /**
     * 切入点表达式
     *
     * @param requireRoles 传入注解参数
     */
    @Pointcut("@annotation(requireRoles)")
    public void authService(RequireRoles requireRoles) {
    }


    /**
     * 切面方法
     * @param joinPoint    方法参数
     * @param requireRoles 方法上的注解
     * @return 方法的执行结果
     * @throws Throwable
     */
    @Around("authService(requireRoles)")
    public Object doAroud(ProceedingJoinPoint joinPoint, RequireRoles requireRoles) throws Throwable {
        Object o = null;
        //获取我们注解中配置的角色信息 返回的是角色id数组
        String[] roles = requireRoles.roles();
        //拿到token在方法参数的位置
        int index = requireRoles.index();
        //拿到token参数
        String token = joinPoint.getArgs()[index].toString();
        //尝试解析token
        Object object = null;
        try {
            object = JWTUtil.parserToken(token, Const.PUBLIC_KEY);
        } catch (Exception e) {
            //解析失败返回前端错误
            return Rsp.fail().code(50008).msg("token失效请重新登陆");
        }
        List<String> list = Arrays.asList(roles);
        //判断是否是否是病人
        if (object instanceof Patient) {
            if (list.contains("patient")) {
                return joinPoint.proceed();
            }
        }else{
            //如果是工作人员判断是否有权限
            List<String> roleId = ((HisUser) object).getRoles();
            if (!Collections.disjoint(list,roleId)) {
                return joinPoint.proceed();
            }
        }
        return Rsp.fail().msg("权限不足");
    }
}
